﻿using System;
using System.Data.SqlClient;
using System.Globalization;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Casamiel.Common;
using Casamiel.Domain.Entity;
using MediatR;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

namespace Casamiel.Application.Commands
{
    /// <summary>
    /// 微信登陆
    /// </summary>
    public sealed class AppWecahtLoginCommandHandler:BaseCommandHandler,IRequestHandler<AppWecahtLoginCommand,Tuple<int,bool,string>>
    {
        private readonly IWxService _wxService;
      
      /// <summary>
      ///  
      /// </summary>
      /// <param name="netICService">Net ICS ervice.</param>
      /// <param name="wxService">Wx service.</param>
      /// <param name="settings">Settings.</param>
      /// <param name="httpClientFactory">Http client factory.</param>
        public AppWecahtLoginCommandHandler(INetICService netICService,IWxService wxService, IOptionsSnapshot<CasamielSettings> settings,IHttpClientFactory httpClientFactory) : base(netICService,httpClientFactory,settings)
        {
            _wxService = wxService;
        }

        /// <summary>
        /// Handle the specified request and cancellationToken.
        /// </summary>
        /// <returns>The handle.</returns>
        /// <param name="request">Request.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task<Tuple<int,bool,string>> Handle(AppWecahtLoginCommand request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            var miniappentity = await _wxService.FindAsync<ICasaMielSession>(request.AppId).ConfigureAwait(false);
            if (miniappentity == null)
            {
                throw new ArgumentException(MessageResource.MiniAppNotConfig);
            }
            string url = "sns/oauth2/access_token?";//https://api.weixin.qq.com/
            string param = string.Format(CultureInfo.CurrentCulture,"appid={0}&secret={1}&code={2}&grant_type={3}", request.AppId, miniappentity.Secret, request.Code, "authorization_code");
            var client = HttpClientFactory.CreateClient("weixin");
            string result = "";
            using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, url + param))
            {
                using (var response = await client.SendAsync(requestMessage,cancellationToken).ConfigureAwait(false))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        result = await response.Content.ReadAsStringAsync( cancellationToken).ConfigureAwait(false);
                    }
                }
            }
                
            var wxopenInfo = JsonConvert.DeserializeObject<dynamic>(result);
            string openid = wxopenInfo.openid;
            string unionId = wxopenInfo.unionid;
            WxOpenId userinfo = await _wxService.GetAsync<ICasaMielSession>(openid, request.AppId).ConfigureAwait(false);
            if (userinfo == null)
            {
                if (string.IsNullOrEmpty(unionId))
                {
                    unionId = "";
                }
                userinfo = new WxOpenId { AppId = request.AppId, OpenId = openid, UnionId = unionId, Session_key = wxopenInfo.session_key, Create_time = DateTime.Now };
                
                try
                {
                    await _wxService.AddAsync<ICasaMielSession>(userinfo).ConfigureAwait(false);
                }
                catch (SqlException ex)
                {
                    if (ex.Number == 2627 || ex.Number != 2601)
                    {
                        userinfo = await _wxService.GetAsync<ICasaMielSession>(openid, request.AppId).ConfigureAwait(false);
                    }
                    else
                    {
                        throw ;
                    }
                }
            }
            else
            {
              //  userinfo.session_key = wxopenInfo.session_key;
                userinfo.Update_time = DateTime.Now;
                if (!string.IsNullOrEmpty(unionId))
                {
                    userinfo.UnionId = unionId;
                }
                await _wxService.UpdateAsync<ICasaMielSession>(userinfo).ConfigureAwait(false);
            }

            if (!string.IsNullOrEmpty(unionId))
            {
                var userentity = await _wxService.GetByUnionIdAsync<ICasaMielSession>(unionId).ConfigureAwait(false);
                if (userentity != null)
                {
                    return new Tuple<int,bool,string>(userinfo.Id,  true, userentity.Mobile);
                }
            }
            if (string.IsNullOrEmpty(userinfo.Mobile))
            {
                return new Tuple<int, bool,string>(userinfo.Id, false,"");
            }
            return new Tuple<int, bool,string>(userinfo.Id, true, userinfo.Mobile);
        }

    //    {
    //"access_token": "",
    //"refresh_token": "",
    //"unionid": "",
    //"openid": "",
    //"scope": "",
    //"expires_in": 7200
//}
}
}
